﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YRevitJig;
using YJKRGeometry;

namespace YJKArch.DimensionModule
{
	public class PracticeDimJig : XUiJigBase
	{
		public PracticeDimJig(UIDocument uiDoc, System.Windows.Forms.Form form) : base(uiDoc)
		{
			this.JigStage = PracticeDimJig.EStage.eNoOper;
			this.m_formPractice = form;
			this.m_UserForm = form;
		}

		public XYZ PickDimPosition(XYZ ptStart, string strPrompt = "请确定标注位置：")
		{
			try
			{
				this.JigStage = PracticeDimJig.EStage.eDimPosition;
				this.StartPoint = ptStart;
				this.DimPosition = base.UiDoc.Selection.PickPoint(strPrompt);
				this.DimPosition = this.GetResetPoint(this.StartPoint, this.DimPosition);
			}
			catch
			{
				this.DimPosition = null;
			}
			this.JigStage = PracticeDimJig.EStage.eNoOper;
			return this.DimPosition;
		}

		public XYZ PickDimDirection(XYZ ptStart, XYZ ptDimPos, string strPrompt = "请确定标注方向：")
		{
			try
			{
				this.JigStage = PracticeDimJig.EStage.eDimDirection;
				this.StartPoint = ptStart;
				this.DimPosition = ptDimPos;
				this.DimDirection = base.UiDoc.Selection.PickPoint(strPrompt);
			}
			catch
			{
				this.DimDirection = null;
			}
			this.JigStage = PracticeDimJig.EStage.eNoOper;
			return this.DimDirection;
		}

		public override void Draw(PaintEventArgs paintEventArgs)
		{
			base.Draw(paintEventArgs);
			if (this.m_ptCur.IsEmpty)
			{
				return;
			}
			XYZ xyz = base.Client2Revit(this.m_ptCur);
			XGraphics xgraphics = new XGraphics(paintEventArgs.Graphics, base.JigPen);
			if (this.JigStage == PracticeDimJig.EStage.eDimPosition)
			{
				xyz = this.GetResetPoint(this.StartPoint, xyz);
				new XLine2D(base.Revit2Client(this.StartPoint), base.Revit2Client(xyz)).Draw(xgraphics);
				return;
			}
			if (this.JigStage == PracticeDimJig.EStage.eDimDirection)
			{
				DlgPracticeDim dlgPracticeDim = this.m_formPractice as DlgPracticeDim;
				dlgPracticeDim.GetDlgData();
				TextNoteType textNoteTypeByName = this.GetTextNoteTypeByName(base.UiDoc.Document, dlgPracticeDim.sFontType);
				if (textNoteTypeByName == null)
				{
					return;
				}
				List<string> list = new List<string>();
				foreach (string item in dlgPracticeDim.textStrArray)
				{
					list.Add(item);
				}
				if (list.Count < 1)
				{
					return;
				}
				new XLine2D(base.Revit2Client(this.StartPoint), base.Revit2Client(this.DimPosition)).Draw(xgraphics);
				list.Reverse();
				if (dlgPracticeDim.bTextOnLine)
				{
					this.DrawTextOnLine(xyz, textNoteTypeByName, xgraphics, list);
					return;
				}
				this.DrawTextEndLine(xyz, textNoteTypeByName, xgraphics, list);
			}
		}

		public int GetQuadrant(XYZ ptOrigin, XYZ ptUser)
		{
			XYZ xyz = (ptUser - ptOrigin).Normalize();
			double val = base.UiDoc.ActiveView.RightDirection.AngleOnPlaneTo(xyz, base.UiDoc.ActiveView.ViewDirection);
			if (Geometry.Lessthan_Or_Equal(val, Math.PI*.5))
			{
				return 1;
			}
			if (Geometry.Lessthan_Or_Equal(val, Math.PI))
			{
				return 2;
			}
			if (Geometry.LessThan(val, 4.71238898038469))
			{
				return 3;
			}
			return 4;
		}

		private void DrawTextOnLine(XYZ ptCursor, TextNoteType txtNoteType, XGraphics graphics, List<string> lstText)
		{
			double num = txtNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
			double num2 = txtNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			double num3 = (double)base.UiDoc.ActiveView.Scale;
			double num4 = num * num2 * num3 * RevitDocumentExtension.GetTextWidthFactory();
			double num5 = num * 2.0 * num3;
			double num6 = (double)lstText.Count * num5;
			double num7 = 1.2;
			XYZ upDirection = base.UiDoc.ActiveView.UpDirection;
			XYZ xyz = this.DimPosition;
			XYZ xyz2 = xyz + num6 * upDirection;
			int quadrant = this.GetQuadrant(this.DimPosition, ptCursor);
			if (quadrant == 3 || quadrant == 4)
			{
				xyz2 = this.DimPosition;
				xyz = xyz2 - num6 * upDirection;
			}
			new XLine2D(base.Revit2Client(xyz2), base.Revit2Client(xyz)).Draw(graphics);
			XYZ xyz3 = base.UiDoc.ActiveView.RightDirection;
			if (quadrant == 2 || quadrant == 3)
			{
				xyz3 = -xyz3;
			}
			int num8 = 0;
			foreach (string str in lstText)
			{
				int num9 = SpecialCharactorDrawingKit.GetLength(str) + 1;
				if (num8 < num9)
				{
					num8 = num9;
				}
			}
			double num10 = (double)num8 * num4 * num7;
			for (int i = 0; i < lstText.Count; i++)
			{
				XYZ xyz4 = xyz + (double)i * num5 * upDirection;
				XYZ point = xyz4 + (num10 + num4) * xyz3;
				new XLine2D(base.Revit2Client(xyz4), base.Revit2Client(point)).Draw(graphics);
				double num11 = (double)SpecialCharactorDrawingKit.GetLength(lstText[i]) * num4 * num7;
				XYZ xyz5 = xyz4 + 0.25 * num5 * upDirection + num4 * xyz3;
				XYZ xyz6 = xyz5 + (num11 + num4) * xyz3;
				new XLine2D(base.Revit2Client(xyz5), base.Revit2Client(xyz6)).Draw(graphics);
				XYZ point2 = xyz5 + 0.5 * num5 * upDirection;
				XYZ point3 = xyz6 + 0.5 * num5 * upDirection;
				new XLine2D(base.Revit2Client(point2), base.Revit2Client(point3)).Draw(graphics);
				new XLine2D(base.Revit2Client(xyz5), base.Revit2Client(point2)).Draw(graphics);
				new XLine2D(base.Revit2Client(xyz6), base.Revit2Client(point3)).Draw(graphics);
			}
		}

		private void DrawTextEndLine(XYZ ptCursor, TextNoteType txtNoteType, XGraphics graphics, List<string> lstText)
		{
			double num = txtNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
			double num2 = txtNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			double num3 = (double)base.UiDoc.ActiveView.Scale;
			double num4 = num * num2 * num3 * RevitDocumentExtension.GetTextWidthFactory();
			double num5 = num * 1.5 * num3;
			double num6 = (double)(lstText.Count - 1) * num5;
			double num7 = 1.2;
			double num8 = AssistFunc.mmToFeet(500.0);
			XYZ upDirection = base.UiDoc.ActiveView.UpDirection;
			XYZ xyz = this.DimPosition;
			XYZ xyz2 = xyz + num6 * upDirection;
			int quadrant = this.GetQuadrant(this.DimPosition, ptCursor);
			if (quadrant == 3 || quadrant == 4)
			{
				xyz2 = this.DimPosition;
				xyz = xyz2 - num6 * upDirection;
			}
			if (xyz2.DistanceTo(xyz) > 0.05)
			{
				new XLine2D(base.Revit2Client(xyz2), base.Revit2Client(xyz)).Draw(graphics);
			}
			XYZ xyz3 = base.UiDoc.ActiveView.RightDirection;
			if (quadrant == 2 || quadrant == 3)
			{
				xyz3 = -xyz3;
			}
			for (int i = 0; i < lstText.Count; i++)
			{
				double num9 = (double)SpecialCharactorDrawingKit.GetLength(lstText[i]) * num4 * num7;
				XYZ xyz4 = xyz + (double)i * num5 * upDirection;
				XYZ xyz5 = xyz4 + num8 * xyz3;
				new XLine2D(base.Revit2Client(xyz4), base.Revit2Client(xyz5)).Draw(graphics);
				xyz4 = xyz5 + num4 * xyz3 - 0.5 * num * num3 * upDirection;
				xyz5 = xyz4 + num9 * xyz3;
				new XLine2D(base.Revit2Client(xyz4), base.Revit2Client(xyz5)).Draw(graphics);
				XYZ point = xyz4 + num * num3 * upDirection;
				XYZ point2 = xyz5 + num * num3 * upDirection;
				new XLine2D(base.Revit2Client(point), base.Revit2Client(point2)).Draw(graphics);
				new XLine2D(base.Revit2Client(xyz4), base.Revit2Client(point)).Draw(graphics);
				new XLine2D(base.Revit2Client(xyz5), base.Revit2Client(point2)).Draw(graphics);
			}
		}

		private XYZ GetResetPoint(XYZ ptBase, XYZ ptUser)
		{
			XYZ result = ptUser;
			DlgPracticeDim dlgPracticeDim = this.m_formPractice as DlgPracticeDim;
			dlgPracticeDim.GetDlgData();
			if (dlgPracticeDim.bSetLeaderAngle)
			{
				double dLineAngle = AssistFunc.AngleToRadian(Convert.ToDouble(dlgPracticeDim.sLeaderAngle));
				result = JigFuncs.GetProjectPoint(base.UiDoc, ptUser, ptBase, dLineAngle);
			}
			return result;
		}

		private TextNoteType GetTextNoteTypeByName(Autodesk.Revit.DB.Document doc, string name)
		{
			TextNoteType textNoteType = null;
			TextNoteType textNoteType2 = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(TextNoteType)))
			{
				TextNoteType textNoteType3 = element as TextNoteType;
				if (textNoteType3 != null)
				{
					if (textNoteType2 == null)
					{
						textNoteType2 = textNoteType3;
					}
					if (textNoteType3.Name.ToString().Equals(name))
					{
						textNoteType = textNoteType3;
						break;
					}
				}
			}
			if (textNoteType == null)
			{
				return textNoteType2;
			}
			return textNoteType;
		}

		public XYZ StartPoint { get; set; }

		public XYZ DimPosition { get; set; }

		public XYZ DimDirection { get; set; }

		public PracticeDimJig.EStage JigStage { get; set; }

		private System.Windows.Forms.Form m_formPractice;

		public enum EStage
		{
			eNoOper,
			eDimPosition,
			eDimDirection
		}
	}
}
